package com.google.code.lightsomy.route;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Route that holds info about url mapping regexp and parameters.
 * 
 * @author Viktoras Agejevas
 *
 */
public class Route {
	
	@SuppressWarnings("unused")
	private static Log log = LogFactory.getLog(Route.class);
	
	private String name;
	
	private String route;
	
	private Pattern pattern;
	
	private String controller;
	
	private String action;
	
	private Map<String, Integer> params;

	
	public Route(String route) {
		setRoute(route);
	}
	
	public Route(String route, String controller, String action) {
		setRoute(route);
		this.controller = controller;
		this.action = action;
	}
	
	public Route(String name, String route, String controller, String action) {
		setRoute(route);
		this.name = name;
		this.controller = controller;
		this.action = action;
	}
	
	protected void parseParameterNames() {
		params = new HashMap<String, Integer>();
		Pattern p = Pattern.compile("<(.+?)>");
		Matcher m = p.matcher(route);

		while(m.find()) {
			params.put(m.group(1), getGroupNumber(m.group(1)));
		}
	}
	
	protected int getGroupNumber(String param) {
		int position = route.indexOf("<" + param + ">");
		String prefix = route.substring(0, position);
		return prefix.split("[(]").length;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj == this) {
			return true;
		}
		if (!(obj instanceof Route)) {
			return false;
		}
		
		Route r = (Route) obj;
		
		return (route == null ? r.getRoute() == null 
							  : route.equals(r.getRoute())) 
			&& (controller == null ? r.getController() == null 
								   : controller.equals(r.getController()))
			&& (action == null ? r.getAction() == null 
							   : action.equals(r.getAction()));

	}

	@Override
	public int hashCode() {
		int result = 1;
		result = 31 * result + route.hashCode();
		result = 31 * result + controller.hashCode();
		result = 31 * result + action.hashCode();
		return result;
	}

	@Override
	public String toString() {
		return "Route: " + name + 
				", regexp: " + route + 
				", controller: " + controller + 
				", action: " + action + 
				", params: " + params;
	}

	public String getRoute() {
		return route;
	}

	public void setRoute(String route) {
		this.route = route;
		pattern = Pattern.compile(route.replaceAll("<.+?>", ""));
		parseParameterNames();
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getController() {
		return controller;
	}

	public void setController(String controller) {
		this.controller = controller;
	}

	public String getAction() {
		return action;
	}

	public void setAction(String action) {
		this.action = action;
	}
	
	public Map<String, Integer> getParams() {
		return new HashMap<String, Integer>(params);
	}

	public Pattern getPattern() {
		return pattern;
	}
	
}
